package com.feige.utils.jwt;

import com.feige.constant.Constants;
import io.jsonwebtoken.*;
import org.joda.time.DateTime;
import org.springframework.util.StringUtils;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

public class JwtUtils {

    private static Key getKeyInstance() {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        byte[] bytes = DatatypeConverter.parseBase64Binary(Constants.APP_SECRET);
        return new SecretKeySpec(bytes,signatureAlgorithm.getJcaName());
    }

    /**
     * 根据JwtInfo生成token
     * @param jwtInfo
     * @return
     */
    public static String getJwtToken(JwtInfo jwtInfo){
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject(jwtInfo.getNum())
                .setIssuedAt(new Date())//颁发时间
                .setExpiration(DateTime.now().plusSeconds(Constants.TOKEN_EXPIRE).toDate())//过期时间
                .claim("id", jwtInfo.getId())//用户id
                .claim("username", jwtInfo.getUsername())//用户昵称
                .claim("num", jwtInfo.getNum())//用户昵称
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }

    /**
     * 根据用户编号生成token
     * @param num
     * @return
     */
    public static String getJwtToken(String num){
        return Jwts.builder()
                .setHeaderParam("typ", "JWT")
                .setHeaderParam("alg", "HS256")
                .setSubject(num)
                .setIssuedAt(new Date())//颁发时间
                .setExpiration(DateTime.now().plusSeconds(Constants.TOKEN_EXPIRE).toDate())//过期时间
                .signWith(SignatureAlgorithm.HS256, getKeyInstance())
                .compressWith(CompressionCodecs.GZIP)
                .compact();
    }


    /**
     * 判断token是否存在与有效
     * @param jwtToken
     * @return
     */
    public static boolean checkJwtTToken(String jwtToken) {
        if(StringUtils.isEmpty(jwtToken)) return false;
        try {
            Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 判断token是否存在与有效
     * @param request
     * @return
     */
    public static boolean checkJwtTToken(HttpServletRequest request) {
        try {
            String jwtToken = request.getHeader(Constants.TOKEN_KEY);
            if(StringUtils.isEmpty(jwtToken)) return false;
            Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 根据token获取会员id
     * @param request
     * @return
     */
    public static JwtInfo getJwtInfoByJwtToken(HttpServletRequest request) {
        String jwtToken = request.getHeader(Constants.TOKEN_KEY);
        if(StringUtils.isEmpty(jwtToken)) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return new JwtInfo(Long.parseLong(claims.get("id").toString()), claims.get("username").toString(),claims.get("num").toString());
    }

    /**
     * 根据token获取用户
     * @param jwtToken
     * @return
     */
    public static String getUsernameFromToken(String jwtToken) {
        if(StringUtils.isEmpty(jwtToken) || "".equals(jwtToken.trim())) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return claims.get("username").toString();
    }

    /**
     * 根据token获取和学号
     * @param jwtToken
     * @return
     */
    public static String getUsernameAndNumFromToken(String jwtToken) {
        if(StringUtils.isEmpty(jwtToken) || "".equals(jwtToken.trim())) return null;
        Jws<Claims> claimsJws = Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwtToken);
        Claims claims = claimsJws.getBody();
        return  claims.get("num").toString() + claims.get("username").toString();
    }
    /**
     * 根据token获取用户
     * @param jwtToken
     * @return
     */
    public static String getNumFromToken(String jwtToken) {
        if(StringUtils.isEmpty(jwtToken) || "".equals(jwtToken.trim())) return null;
        return Jwts.parser()
                .setSigningKey(getKeyInstance())
                .parseClaimsJws(jwtToken)
                .getBody()
                .getSubject();
    }

}
